<template>
  <table
    cellspacing="0"
    cellpadding="0"
    border="0"
    style="table-layout: fixed; border-collapse: separate; border-spacing: 0; width: auto"
  >
    <colgroup>
      <col
        name="selection"
        :width="selection.width"
        v-if="selection.visible"
        :style="{ minWidth: `${selection.width}px` }"
      />
      <col
        v-for="column in columns"
        :key="column.prop"
        :name="column.prop"
        :width="column.width || 'auto'"
        :style="{ minWidth: `${column.minWidth || column.width}px` }"
      />
    </colgroup>
    <thead>
      <tr class="table_header__row" ref="headerRow">
        <th
          style="text-align: left; padding: 0 10px"
          class="no-drag"
          v-if="selection.visible"
          :style="getSelectionStyle()"
        >
          <el-checkbox v-model="checked" @change="handleSelect"></el-checkbox>
        </th>
        <th
          v-for="(column, index) in columns"
          :key="column.prop"
          :style="getColStyle(column)"
          class="resize-column"
          :class="{ 'sticky-shadow': column.fixed && isSrcoll, 'no-drag': disabledMove.includes(column.prop) }"
        >
          <div :style="getCenterStyle(column)">
            <span>{{ column.label }}</span>
            <span class="sortable-span" @click="handleSort(column)" v-if="column.sortable">
              <el-icon
                class="sort-down"
                :class="{ 'sort-active': column.prop == sortColumn.prop && sortColumn.order == 'descending' }"
                ><SortDown
              /></el-icon>
              <el-icon
                class="sort-up"
                :class="{ 'sort-active': column.prop == sortColumn.prop && sortColumn.order == 'ascending' }"
                ><SortUp
              /></el-icon>
            </span>

            <el-popover placement="bottom">
              <section class="fixed-select">
                <div class="fixed-item" @click="handleFixed(column, false)" v-if="column.fixed">
                  <el-icon><Unlock /></el-icon>
                  <span>取消冻结</span>
                </div>
                <div class="fixed-item" @click="handleFixed(column, true)" v-else>
                  <el-icon><Lock /></el-icon>
                  <span>向左冻结</span>
                </div>
              </section>
              <template #reference>
                <span class="fixed-span">
                  <el-icon class="more-filled"><MoreFilled /></el-icon> </span
              ></template>
            </el-popover>
          </div>
          <div
            class="resize-handle"
            @mousedown="startResize($event, index)"
            v-if="!disabledMove.includes(column.prop)"
          ></div>
        </th>
      </tr>
    </thead>
  </table>
</template>

<script>
import Sortable from 'sortablejs';
import { SortDown, SortUp, Unlock, Lock, MoreFilled } from '@element-plus/icons-vue';

export default {
  name: 'TableHeader',
  components: {
    SortDown,
    SortUp,
    Unlock,
    Lock,
    MoreFilled,
  },
  props: {
    columns: {
      type: Array,
      default: () => {
        return [];
      },
    },
    colMinWidth: {
      type: Number,
      default: 100,
    },
    selection: {
      type: Object,
      default: () => {
        return {
          width: 55,
          visible: true,
        };
      },
    },
    disabledMove: {
      type: Array,
      default: () => {
        return [];
      },
    },
    fixdColumns: {
      type: Object,
      default: () => {
        return {};
      },
    },
    isSrcoll: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    isFixed() {
      return Object.keys(this.fixdColumns).length > 0;
    },
  },
  data() {
    return {
      checked: false,
      sortableInstance: null,
      // 拖拽相关状态
      resizingColIndex: -1,
      startX: 0,
      startWidth: 0,
      sortColumn: {
        column: {},
        prop: null,
        order: null,
      },
    };
  },
  created() {},
  mounted() {
    // 初始化 Sortable
    this.initSortable();
  },
  beforeDestroy() {
    // 销毁 Sortable 实例
    if (this.sortableInstance) {
      this.sortableInstance.destroy();
    }
    // 确保在组件销毁时移除所有事件监听器
    this.destroyResize();
  },
  methods: {
    getSelectionStyle() {
      if (!this.isFixed) {
        return {};
      }
      return {
        position: 'sticky',
        'z-index': 10,
        left: 0,
        'background-color': '#ffffff',
      };
    },
    getColStyle(column) {
      if (!this.isFixed || this.fixdColumns[column.prop] === undefined) {
        return { 'text-align': column.align || 'left' };
      }
      const style = {
        'text-align': column.align || 'left',
        position: 'sticky',
        'z-index': 10,
        left: `${this.fixdColumns[column.prop]}px`,
        'background-color': '#ffffff',
      };
      return style;
    },
    getCenterStyle(column) {
      const style = { display: 'flex', 'align-items': 'center' };
      if (column.align === 'center') {
        style['justify-content'] = 'center';
      }
      return style;
    },
    initSortable() {
      const headerRow = this.$refs.headerRow; // 获取表头行的 DOM 引用
      this.sortableInstance = Sortable.create(headerRow, {
        animation: 150, // 动画效果
        filter: '.no-drag',
        onMove: function (evt) {
          // 过滤掉的元素阻止移动
          return evt.related.className.indexOf('no-drag') === -1;
        },
        onEnd: ({ oldIndex, newIndex }) => {
          if (oldIndex !== undefined && newIndex !== undefined) {
            //未实际移动位置
            if (oldIndex === newIndex) {
              return;
            }
            // // 使用解构赋值交换位置
            // [this.columns[oldIndex-1], this.columns[newIndex-1]] = [this.columns[newIndex-1], this.columns[oldIndex-1]];
            this.moveBeforeByProperty(this.columns, newIndex - 1, oldIndex - 1);

            // 将新数据插入到前面
            this.$emit('sort-column', this.columns);
          }
        },
      });
    },
    moveBeforeByProperty(arr, targetIndex, moveIndex) {
      const [removedItem] = arr.splice(moveIndex, 1);
      arr.splice(targetIndex, 0, removedItem);
      return arr;
    },
    startResize(event, index) {
      this.resizingColIndex = index;
      this.startX = event.clientX; // 记录鼠标初始X坐标
      // 获取当前列的实际宽度 (clientWidth 包含了内边距和滚动条宽度)
      this.startWidth = this.$el.querySelectorAll('.resize-column')[index].clientWidth;
      // 绑定全局事件监听器，以便鼠标移出 th 区域也能继续拖拽
      document.addEventListener('mousemove', this.doResize);
      document.addEventListener('mouseup', this.stopResize);
      // 阻止默认文本选择行为
      event.preventDefault();
    },
    doResize(event) {
      if (this.resizingColIndex === -1) return;
      const deltaX = event.clientX - this.startX; // 鼠标移动的距离
      let newWidth = this.startWidth + deltaX;
      // 可选：设置最小宽度
      if (newWidth < this.colMinWidth) {
        newWidth = this.colMinWidth;
      }
      // 更新列宽度数据
      this.columns[this.resizingColIndex].width = newWidth;
    },
    stopResize() {
      this.resizingColIndex = -1;
      // 将新的列宽度保存到后端
      this.$emit('resize-column', this.columns);
      // 移除全局事件监听器
      this.destroyResize();
    },
    destroyResize() {
      document.removeEventListener('mousemove', this.doResize);
      document.removeEventListener('mouseup', this.stopResize);
    },

    handleSelect() {
      this.$emit('select-all', this.checked);
    },
    handleSort(column) {
      if (!this.sortColumn.prop || this.sortColumn.prop !== column.prop) {
        this.sortColumn = {
          column: column,
          prop: column.prop,
          order: 'descending',
        };
        this.$emit('sort-change', this.sortColumn);
        return;
      }
      if (!this.sortColumn.order) {
        this.sortColumn.order = 'descending';
        this.$emit('sort-change', this.sortColumn);
        return;
      }
      if (this.sortColumn.order === 'descending') {
        this.sortColumn.order = 'ascending';
        this.$emit('sort-change', this.sortColumn);
        return;
      }
      this.sortColumn.order = null;
      this.$emit('sort-change', this.sortColumn);
    },

    handleFixed(column, bool) {
      column.fixed = bool;
      this.$emit('fixed-change', column, bool);
    },
    toggleSelection(bool) {
      this.checked = bool;
    },
  },
};
</script>

<style lang="scss" scoped>
.table_header__row {
  height: 36px;
  th {
    padding: 0 8px;
    border-bottom: 1px solid #e8e9e9;

    position: relative; /* 确保 resize-handle 相对定位 */
    /* 确保文本不会溢出导致宽度计算问题 */
    white-space: nowrap;
    /* 拖拽时，内容可能会被选择，可以禁用选择 */
    user-select: none;

    .sortable-span {
      display: inline-block;
      vertical-align: middle;
      margin-left: 4px;
      cursor: pointer;
      font-size: 16px;
      position: relative;
      width: 16px;
      min-width: 12px;
      height: 19px;
      .sort-down {
        position: absolute;
        top: 2.5px;
        left: -2px;
      }
      .sort-up {
        position: absolute;
        top: 1.5px;
        left: 4px;
      }
      .sort-active {
        color: #216ef2;
      }
    }

    .fixed-span {
      display: inline-block;
      vertical-align: middle;
      margin-left: 4px;
      cursor: pointer;
      font-size: 14px;
      width: 14px;
      min-width: 12px;
      height: 19px;
      position: relative;
      .more-filled {
        position: absolute;
        /* 旋转90度 */
        transform: rotate(90deg);
        top: 3.5px;
        left: 0;
      }
    }

    /* 拖拽手柄样式 */
    .resize-handle {
      display: none;
      position: absolute;
      right: 4px;
      top: 0;
      bottom: 0;
      width: 2px;
      background: #216ef2;
      margin: 8px 0;
      border: none;

      cursor: col-resize; /* 左右拖拽光标 */
      z-index: 1; /* 确保手柄在内容之上 */
    }

    /* 鼠标悬停在手柄上时可以改变颜色 */
    .resize-handle:hover {
      width: 4px;
      background: #216ef2;
    }
  }
  th:hover {
    .resize-handle {
      display: block;
    }
  }
}

.fixed-select {
  color: #000819;
  font-size: 14px;
  .fixed-item {
    height: 32px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 16px;
  }

  .fixed-item:hover {
    background: #f1f7ff;
  }
}

/* 拖拽时的占位符样式 */
.sortable-ghost {
  opacity: 0.5;
  background: #c8ebfb;
}

// 固定栏遮罩
.sticky-shadow::after {
  content: '';
  position: absolute;
  top: 0;
  right: -6px;
  height: 100%;
  width: 6px;
  background: linear-gradient(to right, rgba(0, 0, 0, 0.1), transparent);
  pointer-events: none;
}
</style>
